#pragma once
#include <QtGlobal>
#include <QHostAddress>
#include <QMetaType>

// Qt5/6 兼容性处理
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    // Qt6 中 QHostAddress::Any 已被弃用，使用 QHostAddress::AnyIPv4
    #ifndef QHOSTADDRESS_ANY_COMPAT
    #define QHOSTADDRESS_ANY_COMPAT QHostAddress::AnyIPv4
    #endif
#else
    // Qt5 中使用 QHostAddress::Any
    #ifndef QHOSTADDRESS_ANY_COMPAT
    #define QHOSTADDRESS_ANY_COMPAT QHostAddress::Any
    #endif
#endif

/**
 * @brief UDP数据包头结构
 * 
 * 定义UDP数据包的标准格式，包含魔数校验、长度、消息类型等信息。
 * 所有UDP数据包都必须包含此头部结构。
 */
struct QsUdpPacketHeader
{
    char magic[4] = {'Q','U','D','P'}; ///< 魔数校验字符串，用于识别有效数据包
    quint32 length = 0;                 ///< 数据长度（不包含头部）
    quint16 msgType = 0;                ///< 消息类型，用于区分不同的业务逻辑
    quint16 reserved1 = 0;              ///< 预留字段1，可用于扩展
    quint16 reserved2 = 0;              ///< 预留字段2，可用于扩展
};

/**
 * @brief UDP端点信息结构体
 * 
 * 封装UDP通信的端点信息，包含IP地址和端口。
 * 可用于表示发送者、接收者或目标端点。
 */
struct QsUdpInfo
{
    QHostAddress address; ///< IP地址
    quint16 port = 0;     ///< 端口号
    
    /**
     * @brief 默认构造函数
     */
    QsUdpInfo() = default;
    
    /**
     * @brief 带参数的构造函数
     * @param addr IP地址
     * @param p 端口号
     */
    QsUdpInfo(const QHostAddress& addr, quint16 p) : address(addr), port(p) {}
};

Q_DECLARE_METATYPE(QsUdpPacketHeader)
Q_DECLARE_METATYPE(QsUdpInfo)

// 前向声明，避免循环包含
class QsUdp;

/**
 * @brief UDP发送宏定义
 * 
 * 提供便捷的UDP数据发送宏，自动将原始数据转换为QByteArray格式。
 * 
 * @param msgType 消息类型
 * @param data 原始数据指针
 * @param len 数据长度
 * @param r1 保留字段1
 * @param r2 保留字段2
 * 
 * @note 此宏会自动获取QsUdp单例实例并调用send方法
 * @note 使用QByteArray::fromRawData避免数据拷贝，提高性能
 * 
 * @example
 * @code
 * char buffer[1024];
 * // ... 填充数据 ...
 * QS_UDP_SEND(1, buffer, sizeof(buffer), 0, 0);
 * @endcode
 */
#define QS_UDP_SEND(msgType, data, len, r1, r2) \
    QsUdp::instance()->send(msgType, QByteArray::fromRawData((const char*)(data), (len)), r1, r2) 